package com.coms514.scheduleme;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.calendar.CalendarScopes;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.ArrayAdapter;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;

public class Feedback2Activity extends Activity {
	static final String TAG = "Feedback2Activity";
	
	/****/
	// for google play service
	private static final Level LOGGING_LEVEL = Level.OFF;
	private static final String PREF_ACCOUNT_NAME = "accountName";

	static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
	static final int REQUEST_AUTHORIZATION = 1;
	static final int REQUEST_ACCOUNT_PICKER = 2;

	final HttpTransport transport = AndroidHttp.newCompatibleTransport();
	final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();

	GoogleAccountCredential credential;
	com.google.api.services.calendar.Calendar client;
	/****/

	ArrayList<CalendarListItem> calendarList = new ArrayList<CalendarListItem>();
	ArrayAdapter<CalendarListItem> adapter;
	
	SharedPreferences preferences;
	
	private boolean feedback;
	private int checkHours;
	private int checkMins;
	private ArrayList<String> feedbackCalendar; 	/* calendar summary (or title) */
	
	private ToggleButton feedback_onoff_TB;
	private TimePicker check_time_TP;
	private ListView calendar_list_LV;
		
	ScheduleMe	myState;
	int numAsyncTasks;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// view and menu
		setContentView(R.layout.feedback2);

		/****/
		myState = ((ScheduleMe)getApplicationContext());
		//credential = myState.getCredential();
		client = myState.getClient();

		if (client == null) {
			// enable logging
			Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
			
			// Google Accounts
			credential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(CalendarScopes.CALENDAR));
			
			// SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
			SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
			credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
			
			// Calendar client
			client = new com.google.api.services.calendar.Calendar.Builder(
					transport, jsonFactory, credential).setApplicationName("Google-CalendarAndroidSample/1.0")
					.build();
			
			//myState.setCredential(credential);
			myState.setClient(client);
		}
		
		/****/
		CalendarListAsyncTask.run(this);
		
		feedback_onoff_TB = (ToggleButton) findViewById(R.id.feedback_onoff);		
		check_time_TP = (TimePicker) findViewById(R.id.check_time);
		calendar_list_LV = (ListView) findViewById(R.id.calendar_list);
        
        preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        feedback = preferences.getBoolean("feedback", false);
        feedback_onoff_TB.setChecked(feedback);
        
        checkHours = preferences.getInt("checkHours", 21);		/* default is 21:00 */
        checkMins = preferences.getInt("checkMins", 0);
        check_time_TP.setCurrentHour(checkHours);
        check_time_TP.setCurrentMinute(checkMins);
        
        feedbackCalendar = new ArrayList<String>();
        int calendarCount = preferences.getInt("calendarCount", 0);
        for (int i = 0; i < calendarCount; i++) {
        	feedbackCalendar.add(preferences.getString("calendar" + i, null));
        }

//		CalendarListAsyncTask.run(this);
	}
	
	public void onSave(View view) {
		SharedPreferences.Editor editor = preferences.edit();

		feedback = feedback_onoff_TB.isChecked();
		editor.putBoolean("feedback", feedback);
		
		checkHours = check_time_TP.getCurrentHour();
		checkMins = check_time_TP.getCurrentMinute();
		editor.putInt("checkHours", checkHours);
		editor.putInt("checkMins", checkMins);
		
		int i = 0;
		for (CalendarListItem cal : calendarList) {
			if (cal.getSelected()) {
				editor.putString("calendar" + i, cal.getName());
				i++;
			}
		}
		editor.putInt("calendarCount", i);
		
		editor.commit();

		// register alarm
		if (feedback) {

//			Calendar c = Calendar.getInstance();
//			// set the time to checkHours
//			c.set(Calendar.HOUR, (checkHours > 12 ? checkHours % 12 : checkHours));
//			c.set(Calendar.AM_PM, (checkHours >= 12 ? 1 : 0));
//			c.set(Calendar.HOUR_OF_DAY, checkHours);
//			c.set(Calendar.MINUTE, checkMins);
//			println(">>> Feedback2Activity.onSave() c: " + c.toString());

			/****/
			Time t = new Time();
			t.setToNow();
			t.hour = checkHours;
			t.minute = checkMins;
			println(">>> Feedback2Activity.onSave() t: " + t.toString());
			println(">>> Feedback2Activity.onSave() t.year: " + t.year);
			println(">>> Feedback2Activity.onSave() t.month + 1: " + (t.month + 1));
			println(">>> Feedback2Activity.onSave() t.monthDay: " + t.monthDay);
			println(">>> Feedback2Activity.onSave() t.hour: " + t.hour);
			println(">>> Feedback2Activity.onSave() t.minute: " + t.minute);
			/****/
			
			AlarmManager am = (AlarmManager)Feedback2Activity.this.getSystemService(ALARM_SERVICE);
			
			//create a pending intent
			PendingIntent pi = PendingIntent.getBroadcast(Feedback2Activity.this, 0,
					new Intent(Feedback2Activity.this, SMReceiver.class),
					PendingIntent.FLAG_UPDATE_CURRENT);

			if (isAlarmActivated()) {
				//cancel it
				am.cancel(pi);
				println(">>> Feedback2Activity.onSave(): previous alarm canceled!!!");
			}
			
//			am.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),
//					AlarmManager.INTERVAL_DAY, pi);
			am.setRepeating(AlarmManager.RTC_WAKEUP, t.toMillis(false),
					AlarmManager.INTERVAL_HOUR, pi);
			
			println(">>> Feedback2Activity.onSave(): alarm set!!!");

		} else {	// unregister alarm
			
			if (isAlarmActivated()) {
				// build pending intent
				PendingIntent pi = PendingIntent.getBroadcast(Feedback2Activity.this, 0,
						new Intent(Feedback2Activity.this, SMReceiver.class),
						PendingIntent.FLAG_UPDATE_CURRENT);
				
				// get Alarm manager instance
				// cancel it
				AlarmManager am = (AlarmManager)Feedback2Activity.this.getSystemService(ALARM_SERVICE);
				am.cancel(pi);
				
				println(">>> Feedback2Activity.onSave(): alarm canceled!!!");
			}
		}
		
		finish();
	}

	/****/
	private boolean isAlarmActivated() {
		PendingIntent pi = PendingIntent.getBroadcast(Feedback2Activity.this, 0,
			   new Intent(Feedback2Activity.this, SMReceiver.class),
			   PendingIntent.FLAG_NO_CREATE);
		if (pi != null) {
			return true;
		} else {
			return false;
		}
	}
	/****/
	
	public void onCancel(View view) {
		finish();
	}
	
	void displayData() {
			 
		for (CalendarListItem cal : calendarList) {
			if (feedbackCalendar.contains(cal.getName())) {
				cal.setSelected(true);
			} else {
				cal.setSelected(false);
			}
		}

		adapter = new MyAdapter(this, R.layout.feedbacklistitem, calendarList);
		calendar_list_LV.setAdapter(adapter);

		calendar_list_LV.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				CalendarListItem cal = (CalendarListItem) parent.getItemAtPosition(position);
				Toast.makeText(getApplicationContext(), "Clicked on : " + cal.getName(),
						Toast.LENGTH_LONG).show();
			}
		});
	}
	  	
	public class MyAdapter extends ArrayAdapter<CalendarListItem> {
    	 
		public MyAdapter(Context context, int textViewResourceId, ArrayList<CalendarListItem> objects) {
			super(context, textViewResourceId, objects);
		}

		private class ViewHolder {
			TextView summaryTextView;
			CheckBox caleandarSelectedCB;
		}
		
		public View getView(int position, View convertView, ViewGroup parent) {
			
			ViewHolder holder = null;

			Log.v(TAG, String.valueOf(position));

			if (convertView == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

				convertView = vi.inflate(R.layout.feedbacklistitem, null);

				holder = new ViewHolder();
				holder.summaryTextView = (TextView) convertView.findViewById(R.id.summary_entry);
				holder.caleandarSelectedCB = (CheckBox) convertView.findViewById(R.id.selected_checkbox);

				convertView.setTag(holder);

				holder.caleandarSelectedCB.setOnClickListener(new View.OnClickListener() {
					public void onClick(View v) {
						CheckBox cb = (CheckBox) v;
						CalendarListItem cal = (CalendarListItem) cb.getTag();

//						Toast.makeText(getApplicationContext(), "Checkbox: " + cb.getText()
//								+ " -> " + cb.isChecked(), Toast.LENGTH_LONG)
//								.show();

						cal.setSelected(cb.isChecked());
					}
				});

			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			CalendarListItem cal = calendarList.get(position);

			holder.summaryTextView.setText(cal.getName());
			// holder.caleandarSelectedCB.setText(cal.getName());
			holder.caleandarSelectedCB.setChecked(cal.getSelected());

			holder.caleandarSelectedCB.setTag(cal);

			return convertView;
		}
	}
	    
	
	/****/
	// for google play service
	void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
		runOnUiThread(new Runnable() {
			public void run() {
				Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
						connectionStatusCode, Feedback2Activity.this, REQUEST_GOOGLE_PLAY_SERVICES);
				dialog.show();
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();
		//if (checkGooglePlayServicesAvailable()) {
			//haveGooglePlayServices();
		//}
	}
  
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		switch (requestCode) {
			case REQUEST_GOOGLE_PLAY_SERVICES:
				if (resultCode == Activity.RESULT_OK) {
					haveGooglePlayServices();
				} else {
					checkGooglePlayServicesAvailable();
				}
				break;
			case REQUEST_AUTHORIZATION:
				if (resultCode == Activity.RESULT_OK) {
					CalendarListAsyncTask.run(this);
				} else {
					chooseAccount();
				}
				break;
			case REQUEST_ACCOUNT_PICKER:
				if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
					String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
					if (accountName != null) {
						credential.setSelectedAccountName(accountName);
						// SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
						SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
						SharedPreferences.Editor editor = settings.edit();
						editor.putString(PREF_ACCOUNT_NAME, accountName);
						editor.commit();
						
						CalendarListAsyncTask.run(this);
					}
				}
				break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.menu_refresh:
				CalendarListAsyncTask.run(this);
				break;
			case R.id.menu_accounts:
				chooseAccount();
				return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/** Check that Google Play services APK is installed and up to date. */
	private boolean checkGooglePlayServicesAvailable() {
		final int connectionStatusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
		
		if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
			showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
			return false;
		}
		return true;
	}

	private void haveGooglePlayServices() {
		// check if there is already an account selected
		if (credential.getSelectedAccountName() == null) {
			// ask user to choose account
			chooseAccount();
		} else {
			// load calendars
			CalendarListAsyncTask.run(this);
		}
	}

  	private void chooseAccount() {
  		startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
  	}
  	
  	/****/
	
	/* for logging */
	private void println(String msg) {
		Log.d(TAG, msg);
	}
}
